package com.mai4j.maiadmin.configure;

import org.jooq.tools.reflect.Reflect;
import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;

import java.util.HashMap;
import java.util.Map;

/**
 * 微信公众号请关注: 开源螺丝钉
 * <br>
 * 码云请关注: <a href="https://gitee.com/xiyoufang">https://gitee.com/xiyoufang</a>
 * <br>
 * 哔哩哔哩请关注: <a href="https://space.bilibili.com/438927834">https://space.bilibili.com/438927834</a>
 * <p>
 * 使用 redis 而不是 ehcache3 时
 *
 * @author xiyoufang
 */
@Configuration
public class RedisCacheConfig {

    @Bean
    public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory, MaiProperties maiProperties) {
        Map<String, RedisCacheConfiguration> cacheConfigurations = generateCacheConfigMap(maiProperties);
        RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
                .disableCachingNullValues()
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
        return RedisCacheManager.builder(redisConnectionFactory)
                .cacheDefaults(cacheConfiguration)
                .withInitialCacheConfigurations(cacheConfigurations).build();
    }

    private Map<String, RedisCacheConfiguration> generateCacheConfigMap(MaiProperties maiProperties) {
        Map<String, RedisCacheConfiguration> initialCacheConfiguration = new HashMap<>();
        MaiProperties.Cache cache = maiProperties.getCache();
        Map<String, Reflect> fields = Reflect.on(cache).fields();
        for (Map.Entry<String, Reflect> itemEntry : fields.entrySet()) {
            MaiProperties.Cache.Item item = itemEntry.getValue().get();
            initialCacheConfiguration.put(item.getName(), RedisCacheConfiguration.defaultCacheConfig()
                    .disableCachingNullValues()
                    .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()))
                    .entryTtl(item.getTtl()));
        }
        return initialCacheConfiguration;
    }
}
